package cn.iocoder.yudao.module.system.service.question;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.module.system.util.StringUtilExtend;
import cn.iocoder.yudao.module.system.dal.dataobject.answer.UserAnswerDO;
import cn.iocoder.yudao.module.system.dal.dataobject.question.*;
import cn.iocoder.yudao.module.system.dal.mysql.question.QuestionChoiceMapper;
import cn.iocoder.yudao.module.system.service.answer.UserAnswerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xingyuv.jushauth.utils.StringUtils;
import org.springframework.stereotype.Service;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import cn.iocoder.yudao.module.system.controller.admin.question.vo.*;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.system.dal.mysql.question.QuestionMapper;


import javax.annotation.Resource;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 问题 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class QuestionServiceImpl implements QuestionService {

    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private QuestionChoiceMapper choiceMapper;
    @Resource
    private UserAnswerService userAnswerService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createQuestion(QuestionSaveReqVO createReqVO) {
        // 插入
        QuestionDO question = BeanUtils.toBean(createReqVO, QuestionDO.class);
        questionMapper.insert(question);

        // 插入子表
        createChoiceList(question.getId(), createReqVO.getChoices());
        // 返回
        return question.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateQuestion(QuestionSaveReqVO updateReqVO) {
        // 校验存在
        validateQuestionExists(updateReqVO.getId());
        // 更新
        QuestionDO updateObj = BeanUtils.toBean(updateReqVO, QuestionDO.class);
        questionMapper.updateById(updateObj);

        // 更新子表
        updateChoiceList(updateReqVO.getId(), updateReqVO.getChoices());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteQuestion(Integer id) {
        // 校验存在
        validateQuestionExists(id);
        // 删除
        questionMapper.deleteById(id);

        // 删除子表
        deleteChoiceByQuestionId(id);
    }

    private void validateQuestionExists(Integer id) {
        if (questionMapper.selectById(id) == null) {
            throw exception(QUESTION_NOT_EXISTS);
        }
    }


    @Override
    public PageResult<QuestionDO> getQuestionPage(QuestionPageReqVO pageReqVO) {
        return questionMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（问题选项） ====================

    @Override
    public List<QuestionChoiceDO> getChoiceListByQuestionId(Integer questionId) {
        return choiceMapper.selectListByQuestionId(questionId);
    }


    private void createChoiceList(Integer questionId, List<QuestionChoiceDO> list) {
        list.forEach(o -> o.setQuestionId(questionId));
        choiceMapper.insertBatch(list);
    }

    private void updateChoiceList(Integer questionId, List<QuestionChoiceDO> list) {
        deleteChoiceByQuestionId(questionId);
        list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createChoiceList(questionId, list);
    }

    private void deleteChoiceByQuestionId(Integer questionId) {
        choiceMapper.deleteByQuestionId(questionId);
    }

    /**
     * 重新答题
     *
     * @return
     */
    @Override
    public QuestionVo answerQuestion(Integer questionId, Integer answerNo) {
        //查询题目
        QuestionDO questionDO = questionMapper.selectById(questionId);
        System.out.println("查询到的问题: " + questionDO);
        QuestionVo vo = new QuestionVo();
        //封装问题
        BeanUtils.copyProperties(questionDO, vo);
        //如果问题类型不为问答题。加载问题选项
        if (questionDO.getType() == 1 || questionDO.getType() == 2) {
            //封装问题选项
            vo.setQuestionChoiceDoS(choiceMapper.selectListByQuestionId(questionId));
        }

        //查询用户的答题记录
        UserAnswerDO oldUserAnswer = userAnswerService.getOldUserAnswer(questionId, answerNo, 1);
//        if (oldUserAnswer != null) {
//            vo.setIsAnswered(1);
//            if (StringUtils.isNotEmpty(oldUserAnswer.getWriteContent())) {
//                vo.setWriteContent(oldUserAnswer.getWriteContent());
//            }
//            if (StringUtils.isNotEmpty(oldUserAnswer.getAnswerChoices())) {
//                vo.setChoosedIds(StringUtilExtend.transferStringToList(oldUserAnswer.getAnswerChoices()));
//            }
//        } else {
//            vo.setIsAnswered(0);
//        }
        return vo;
    }

    @Override
    public QuestionDO getQuestion(Integer id) {
        return questionMapper.selectById(id);
    }

    @Override
    public Integer getBiggestQuestionIdByType(Integer type) {
        QueryWrapper<QuestionDO> wrapper = new QueryWrapper<>();
        wrapper.eq("type", type).eq("status",1).orderByDesc("id").last("limit 1");
        QuestionDO questionDO = questionMapper.selectOne(wrapper);
        return questionDO.getId();
    }

    /**
     * 一次性查询所有题目
     */
    @Override
    public List<QuestionVo> loadQuestionByType(Integer type) {
        //查询所有问题
        QueryWrapper<QuestionDO> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1);
        if (type == 1) {
            wrapper.eq("is_test", 1);
        } else if (type == 2) {
            wrapper.eq("is_pro", 1);
        }
        List<QuestionDO> questionDOS = questionMapper.selectList(wrapper);
        //查询所有的问题选项
        List<QuestionChoiceDO> choiceDOS = choiceMapper.selectList();
        List<QuestionVo> questionVos = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(questionDOS) && CollectionUtil.isNotEmpty(choiceDOS)) {
            for (QuestionDO questionDO : questionDOS) {
                QuestionVo vo = new QuestionVo();
                BeanUtils.copyProperties(questionDO, vo);
                List<QuestionChoiceDO> questionChoiceDOS = new ArrayList<>();
                for (QuestionChoiceDO choiceDO : choiceDOS) {
                    if ((int) choiceDO.getQuestionId() == questionDO.getId()) {
                        questionChoiceDOS.add(choiceDO);
                    }
                }
                vo.setQuestionChoiceDoS(questionChoiceDOS);
                questionVos.add(vo);
            }
        }
        return questionVos;
    }
}